<template>
  <div
      v-if = "!item.meta || !item.meta.hidden"
      class = "sidebar-item-container"
  >
    <!-- 只渲染一个路由 并且路由只有一个子路由时直接渲染这个子路由 -->
    <template
        v-if = "isRenderSingleRoute && theOnlyOneChildRoute"
    >
      <sidebar-item-link
          v-if = "theOnlyOneChildRoute.meta"
          :to = "resolvePath(theOnlyOneChildRoute.path)"
      >
        <el-menu-item
            :index = "resolvePath(theOnlyOneChildRoute.path)"
        >
          <i v-if = "icon && icon.includes('el-icon')" :class = "icon"></i>
          <svg-icon
              v-else-if = "icon"
              class = "menu-icon"
              :icon-class = "icon"
          ></svg-icon>
          <template #title>
            <span>{{ theOnlyOneChildRoute.meta.title }}</span>
          </template>
        </el-menu-item>
      </sidebar-item-link>
    </template>
    <!-- 有多个子路由时 -->
    <el-submenu
        v-else
        :index = "resolvePath(item.path)"
        popper-append-to-body
    >
      <template #title>
        <i
            v-if = "item.meta && item.meta.icon.includes('el-icon')"
            :class = "icon"
        ></i>
        <svg-icon
            v-else-if = "item.meta && item.meta.icon"
            class = "menu-icon"
            :icon-class = "item.meta.icon"
        ></svg-icon>
        <span v-if = "item.meta" class = "submenu-title">{{ item.meta.title }}</span>
      </template>
      <template v-if = "item.children">
        <sidebar-item
            v-for = "child in item.children"
            :key = "child.path"
            :is-nest = "true"
            :item = "child"
            :base-path = "resolvePath(child.path)"
        >
        </sidebar-item>
      </template>
    </el-submenu>
  </div>
</template>

<script lang = "ts">
import { computed, defineComponent, PropType, toRefs } from 'vue'
import path from 'path'
import SidebarItemLink from '@/components/Sidebar/SidebarItemLink.vue'
import { isExternal } from '@/utils/validate'
import { MenuItemRouter } from '@/router/type'

export default defineComponent({
  name: 'SidebarItem',
  props: {
    item: {
      type: Object as PropType<MenuItemRouter>,
      require: true
    },
    basePath: {
      type: String,
      require: true
    }
  },
  components: {
    SidebarItemLink
  },
  setup(props) {
    const { item } = toRefs(props)

    /* 计算子路由个数 hidden除外 */
    const showingChildNumber = computed(() => {
      const children = (props?.item?.children || []).filter(child => {
        if ( child.meta && child.meta.hidden ) return false
        return true
      })
      return children.length
    })

    /* 渲染单个路由 如果该路由只有一个子路由  直接默认渲染子路由 */
    const theOnlyOneChildRoute = computed(() => {
      if ( showingChildNumber.value > 1 ) {
        return null
      }

      if ( item?.value?.children ) {
        for ( const child of item.value.children ) {
          if ( !child.meta || !child.meta.hidden ) {
            return child
          }
        }
      }

      return {
        ...props.item,
        path: ''
      }
    })

    // 是否有可渲染子路由
    const noShowingChildren = computed(() => showingChildNumber.value === 0)

    /* 获取路由的icon图标 */
    const icon = computed(() => {
      return (theOnlyOneChildRoute.value as MenuItemRouter).meta?.icon || (props?.item?.meta && props.item.meta.icon)
    })

    /* 实现父类的路径 以及子类的路径拼接 */
    const resolvePath = (childPath: string) => {
      if ( isExternal(childPath) ) {
        return childPath
      }
      return path.resolve(props.basePath!, childPath)
    }

    const alwaysShowRootMenu = computed(() => props?.item?.meta && props.item.meta.alwaysShow)
    const isRenderSingleRoute = computed(
        () => !alwaysShowRootMenu.value && (!(theOnlyOneChildRoute.value as MenuItemRouter)?.children || noShowingChildren.value)
    )

    return {
      theOnlyOneChildRoute,
      icon,
      resolvePath,
      noShowingChildren,
      isRenderSingleRoute
    }
  }
})
</script>

<style lang = "scss">
.sidebar-item-container {
  text-align: left;
  .menu-icon {
    margin-right: 16px;
    margin-left: 5px;
    vertical-align: middle;
  }
}
</style>
